package edu.jhu.tcj.purfuit;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class QuestionFactory {

	private Map<Category, List<Question>> unusedQuestions = new HashMap<Category, List<Question>>();
	private Map<Category, List<Question>> usedQuestions = new HashMap<Category, List<Question>>();
	
	private static QuestionFactory instance;
	private static File questionDirectory;
	
	private QuestionFactory(File directory) {
		if (directory.isDirectory()) {
			File[] listFiles = directory.listFiles();
			for (File file : listFiles) {
				if (file.getName().contains(".xml")) {
				try {
					Question[] questions = Question.loadQuestion(file);
					for (Question question : questions) {
						List<Question> list = unusedQuestions.get(question.getCategory());
						if (list == null) {
							list = new ArrayList<Question>();
						}
						list.add(question);
						unusedQuestions.put(question.getCategory(), list);
					}
				} catch (QuestionException e) {
					System.err.println(e.getErrorMessage());
					e.printStackTrace();
				}
				}
			}
		}
	}
	
	public static QuestionFactory getInstance(File directory) {
		if (questionDirectory == null || !questionDirectory.getAbsolutePath().equals(directory.getAbsolutePath())) {
			questionDirectory = directory;
			instance = new QuestionFactory(directory);
		}
		return instance;
	}
	
	public static QuestionFactory getInstance() {
		return instance;
	}
	
	public Question generateQuestion(Category category) {
		List<Question> questionList = unusedQuestions.get(category);
		List<Question> usedQuestionList = usedQuestions.get(category);
		if (questionList.isEmpty()) {
			questionList.addAll(usedQuestionList);
		}
		if (questionList.isEmpty()) {
			Question question = new Question();
			//TODO Handle error condition
			return question;
		}
		int size = questionList.size();
		int index = (int)Math.floor(Math.random()*size);
		Question question = questionList.get(index);
		questionList.remove(index);
		if (usedQuestionList == null) {
			usedQuestionList = new ArrayList<Question>();
		}
		usedQuestionList.add(question);
		unusedQuestions.put(category, questionList);
		usedQuestions.put(category, usedQuestionList);
		return question;
	}
	
	public Map<Category, List<Question>> getAllQuestions() { 
		Map<Category, List<Question>> questions = new HashMap<Category, List<Question>>();
		questions.putAll(usedQuestions);
		questions.putAll(unusedQuestions);
		return questions;
	}
	
	/**
	 * Used in saving a game to file
	 * @return
	 */
	public List<String> getUsedQuestionIDs() {
		if(usedQuestions == null || usedQuestions.isEmpty()){
			if(usedQuestions == null) System.out.println("null");
			return null;
		}
		ArrayList<String> usedQuesList = new ArrayList<String>();
		ArrayList<Question> usedList = new ArrayList<Question>();
		for(Map.Entry<Category, List<Question>> entry: usedQuestions.entrySet()){
			usedList.addAll(entry.getValue());
		}
		for(Question ques: usedList){
			usedQuesList.add("" + ques.getID());
		}

		return usedQuesList;
	}
	
	/**
	 * used in loading a game from a file
	 */
	public void loadUsedQuestions(String usedStr){
		StringTokenizer str = new StringTokenizer(usedStr, ",");
	    ArrayList<Question> usedLoadQuestions = new ArrayList();
		while (str.hasMoreTokens()){
	    	String nextToken = str.nextToken();
	    	if ("none".equalsIgnoreCase(nextToken)) {
	    		nextToken = "-1";
	    	}
			int quesNumber = Integer.parseInt(nextToken);
	    	ArrayList<Question> fullList = new ArrayList();
	 		for(Map.Entry<Category, List<Question>> entry: unusedQuestions.entrySet()){
				fullList.addAll(entry.getValue());
			}
	 		
	 		for(Question ques: fullList){
	 			if(ques.getID() == quesNumber){
	 				usedLoadQuestions.add(ques);
	 			}
	 		}
	    }
		
		for(Question used: usedLoadQuestions){
			List<Question> questionList = unusedQuestions.get(used.getCategory());
			List<Question> usedQuestionList = usedQuestions.get(used.getCategory());
			
			if (usedQuestionList == null) {
				usedQuestionList = new ArrayList<Question>();
			}
			
			questionList.remove(used);
			usedQuestionList.add(used);
			
			unusedQuestions.put(used.getCategory(), questionList);
			usedQuestions.put(used.getCategory(), usedQuestionList);
		}
	}

}
